package com.zbkj.client.config;

import cn.hutool.core.util.ObjectUtil;
import com.zbkj.client.utils.ResponseUtil;
import com.zbkj.common.model.admin.SystemAdmin;
import com.zbkj.common.response.ClientLoginResponse;
import com.zbkj.common.result.CommonResult;
import com.zbkj.common.vo.LoginUserVo;
import com.zbkj.service.service.SystemAdminService;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * 客户端token过滤器 验证token有效性
 */
public class ClientJwtAuthenticationTokenFilter extends OncePerRequestFilter {

    private static final Logger logger = LoggerFactory.getLogger(ClientJwtAuthenticationTokenFilter.class);

    @Resource
    private ClientTokenComponent tokenComponent;

    @Autowired
    private ClientSecurityProperties securityProperties;
    
    @Autowired
    private SystemAdminService systemAdminService;
    
    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String requestURI = request.getRequestURI();
        String method = request.getMethod();

        logger.debug("客户端JWT过滤器处理请求: {} {}", method, requestURI);

        // 检查是否启用JWT过滤器
        if (!securityProperties.isEnableJwtFilter()) {
            logger.debug("客户端JWT过滤器：已禁用，跳过验证，请求URI: {}", requestURI);
            filterChain.doFilter(request, response);
            return;
        }
        
        // 检查是否是排除的路径（这些路径由Spring Security配置处理，不需要在这里验证）
        if (isExcludedPath(requestURI)) {
            logger.debug("客户端JWT过滤器：跳过token验证（由Spring Security处理），请求URI: {}", requestURI);
            filterChain.doFilter(request, response);
            return;
        }
        
        // 特殊处理 /dp/** 路径
        if (requestURI.startsWith("/dp/")) {
            logger.debug("客户端JWT过滤器：跳过数字人回调接口验证，请求URI: {}", requestURI);
            filterChain.doFilter(request, response);
            return;
        }
        
        if (requestURI.startsWith("/ws") || requestURI.equals("/ws")) {
            // 放行 WebSocket 握手请求
            filterChain.doFilter(request, response);
            return;
        }

        if (requestURI.startsWith("/api/client/common/proxyImage")) {
            // 放行 防盗链接口
            filterChain.doFilter(request, response);
            return;
        }

        //跳过SSE的连接
//        if (requestURI.startsWith("/api/client/sse")) {
//            // sse的链接放行
//            filterChain.doFilter(request, response);
//            return;
//        }

//        if (requestURI.startsWith("/api/client/index")) {
//            // sse的链接放行
//            filterChain.doFilter(request, response);
//            return;
//        }

        if (requestURI.startsWith("/dr")) {
            // python端调用，写入agent、group信息
            filterChain.doFilter(request, response);
            return;
        }
        
        try {
            // 获取token中的用户ID
            Integer userId = tokenComponent.getLoginUser(request);

            String token = tokenComponent.getToken(request);

            logger.info("用户传入的token：{},请求URI: {}", request.getHeader("token"), requestURI);

            if (ObjectUtil.isNull(userId) || ObjectUtil.isEmpty(userId)) {
                logger.warn("客户端JWT过滤器：token无效或用户ID为空，请求URI: {}", requestURI);
                
                // 返回CommonResult格式的401错误
                sendCommonResultResponse(response, 401, "未登录");
                return;
            }
            
            logger.debug("客户端JWT过滤器：用户ID验证成功，userId: {}, 请求URI: {}", userId, requestURI);

            //查看redis中有没有用户信息，没有的话，则添加进去
            ClientLoginResponse clientLoginResponse = tokenComponent.getUserInfo(userId, token);
            // 关键修复：将认证信息设置到Spring Security上下文中
            if (clientLoginResponse != null) {
                // 创建LoginUserVo对象
                LoginUserVo loginUserVo = new LoginUserVo();
                loginUserVo.setToken(token);
                
                // 从数据库获取SystemAdmin对象
                SystemAdmin systemAdmin = systemAdminService.getById(userId);
                
                if (systemAdmin != null) {

                    //判断积分是不是充足的，如果积分不足，返回10010，积分不足
                    if(isPointUrl(requestURI)) {
                        //获取用户积分
                        Double merchantPowerPoint = tokenComponent.getMerchantPowerPoint(systemAdmin.getMerId());
                        if(merchantPowerPoint <= 0.0){
                            // 返回CommonResult格式的401错误
                            sendCommonResultResponse(response, 10010, "积分不足");
                            return;
                        }
                    }

                    //判断套餐过期
                    Date currentDate = new Date(); // 当前时间
                    if(currentDate.after(systemAdmin.getExpiredTime())){
                        // 套餐过期时间判断
                        sendCommonResultResponse(response, 10012, "您的套餐已经到期");
                        return;
                    }

                    loginUserVo.setUser(systemAdmin);
                    
                    // 创建认证token
                    UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
                        loginUserVo, null, null);
                    authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                    
                    // 设置到Spring Security上下文
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                    
                    logger.debug("客户端JWT过滤器：认证信息已设置到Spring Security上下文，userId: {}, username: {}", 
                                userId, systemAdmin.getAccount());
                } else {
                    logger.warn("客户端JWT过滤器：无法获取用户信息，userId: {}", userId);
                    sendCommonResultResponse(response, 401, "未登录");
                    return;
                }
            }
            
            // 如果token有效，继续处理请求
            filterChain.doFilter(request, response);
            
        } catch (Exception e) {
            logger.error("客户端JWT过滤器处理异常，请求URI: {}, 错误信息: {}", requestURI, e.getMessage(), e);
            
            // 处理其他异常，返回CommonResult格式的错误
            sendCommonResultResponse(response, 500, "系统异常：" + e.getMessage());
        }
    }

    /**
     * 发送CommonResult格式的响应
     */
    private void sendCommonResultResponse(HttpServletResponse response, int code, String message) throws IOException {
        response.setStatus(HttpServletResponse.SC_OK);
        response.setContentType("application/json;charset=UTF-8");
        
        CommonResult<?> result = CommonResult.failed(message);
        result.setCode(code);
        
        String jsonResponse = objectMapper.writeValueAsString(result);
        response.getWriter().write(jsonResponse);
    }

    /**
     * 检查请求路径是否在排除列表中
     * 这些路径由Spring Security配置处理，JWT过滤器不需要验证
     *
     * @param requestURI 请求URI
     * @return 是否排除
     */
    private boolean isExcludedPath(String requestURI) {
        List<String> excludePaths = securityProperties.getExcludePaths();
        return excludePaths.stream().anyMatch(requestURI::startsWith);
    }

    /**
     * 查看请求路径是否需要判断积分是否充足的接口
     * @param requestURI
     * @return
     */
    private boolean isPointUrl(String requestURI) {
        //需要判断积分的接口
        List<String> list = Arrays.asList(
                "/api/client/index/userLocationFix",//用户定位确认
                "/api/client/index/changeBatchTask",//周任务换一批
                "/api/client/index/contentCreate",//文案创作
                "/api/client/index/magicPen", //魔法笔
                "/api/client/message/sendMessage", //发送消息
                "/api/client/digital-person/addDpVideo", //合成数字人视频
                "/api/client/digital-person/addDpVoice", //合成声音
                "/api/client/workbench/videoSplit", //视频拆解
                "/api/client/workbench/videoSubtitle", //视频转文案
                "/api/client/workbench/videoTemplatePreview", //模板成片预览
                "/api/client/workbench/videoTemplateCreate", //模板成片最终合成
                "/api/client/workbench/videoTemplateEdit", //模板成片编辑
                "/api/client/workbench/replacePic"//替换素材
        );


        return list.contains(requestURI);
    }
} 